package main

import "fmt"

func main() {
	/*
		1、指针
		·变量的本质是给存储数据的内存地址起了一个好记的别名，比如定义一个变量 a:=10，这时直接通过
		  a这个变量来读取内存中保存10的这个值。在计算机底层a这个变量其实对应了一个内存地址
		·指针也是一个变量，但它是一种特殊的变量，它存储的数据不是一个普通的值，而是另一个变量的内存地址
	*/
	var a int = 10
	fmt.Printf("a的类型是：%T,a的值是：%v，a的地址是：%p\n", a, a, &a)
	//a的类型是：int,a的值是：10，a的地址是：0x1400009c018

	var p = &a
	fmt.Printf("p的类型是：%T,p的值是：%v\n", p, p)
	//p的类型是：*int,p的值是：0x1400000e0a8

	/*
		    2、指针地址和指针类型
			每个变量在运行时都会有一个地址，改地址代表变量在内存中的位置，Go中&字符放在变量前面
			对变量进行去地址操作。Go中值类型（int,float,bool,string,array,struct）都有对应
			指针类型，如*int，*int64，*string
	*/
	var b int = 100
	var b1 = &b
	fmt.Printf("b的地址:%p,b1的地址：%p,b的值：%v\n", b1, &b1, *b1)
	//b的地址:0x14000110030,b1的地址：0x14000116020,b的值：100

	/*
	 3、地址取值 *取值 可以取出改变量对应地址存储的值
	  通过 *修改的值会影响其指定的地址存储值，因为其本就是引用 类型
	*/
	var c = "hello golang"
	c1 := &c
	c2 := &c1
	fmt.Printf("c的地址：%p,c1的地址：%p,c2的地址：%p,c的值:%v\n", c1, c2, &c2, *c1)
	fmt.Printf("c的地址：%p,c1的地址：%p,c2的地址：%p,c的值:%v\n", &c, &c1, &c2, c)
	//	c的地址：0x1400008e020,c1的地址：0x140000a2028,c2的地址：0x140000a2030,c的值:hello golang
	// c的地址：0x1400008e020,c1的地址：0x140000a2028,c2的地址：0x140000a2030,c的值:hello golang
	*c1 = "hello js"
	fmt.Printf("c的新值：%v\n", c) //c的新值：hello js

}
